package com.holly.unit.bpmn.designer.core.bpmn;

import cn.hutool.core.util.StrUtil;
import com.holly.unit.bpmn.designer.constants.BpmnDesignerConstants;
import org.activiti.bpmn.model.*;
import org.activiti.engine.delegate.ExecutionListener;

import java.util.ArrayList;
import java.util.List;

/**
 * 类描述: Activiti BpmnModelFactory实现
 *
 * @author fxr
 * @version 1.0.0
 * @date 2022/5/12 10:45
 */
public class BpmnModelActImpl implements BpmnModelFactory {

    @Override
    public StartEvent createStartEvent(String id,String name) {
        StartEvent startEvent = new StartEvent();
        startEvent.setId(id);
        startEvent.setName(name);
        return startEvent;
    }

    @Override
    public UserTask createUserTask(String id, String name, String assignee) {
        UserTask userTask = new UserTask();
        userTask.setId(id);
        userTask.setName(name);
        userTask.setAssignee(assignee);
        return userTask;
    }

    @Override
    public UserTask createCandidateUsersTask(String id, String name, List<String> userIds) {
        UserTask userTask = new UserTask();
        userTask.setId(id);
        userTask.setName(name);
        userTask.setCandidateUsers(userIds);
        return userTask;
    }

    @Override
    public UserTask createCandidateGroupsTask(String id, String name, List<String> roleIds) {
        UserTask userTask = new UserTask();
        userTask.setId(id);
        userTask.setName(name);
        userTask.setCandidateGroups(roleIds);
        return userTask;
    }

    @Override
    public UserTask createAssigneeUserTask(String id, String name, String assignee) {
        UserTask userTask = new UserTask();
        userTask.setId(id);
        userTask.setName(name);
        userTask.setAssignee(assignee);
        return userTask;
    }


    @Override
    public UserTask createCountersignCandidateUsersTask(String id, String name, String assigneeList,
                                                        String assigneeName,String completionCondition,
                                                        String assignee,List<String> userIds) {
        UserTask userTask = new UserTask();
        userTask.setId(id);
        userTask.setName(name);

        MultiInstanceLoopCharacteristics characteristics = new MultiInstanceLoopCharacteristics();
        // 审批人集合参数
        characteristics.setInputDataItem(assigneeList);
        // 迭代集合
        characteristics.setElementVariable(assigneeName);

        // 完成条件
        characteristics.setCompletionCondition(completionCondition);
        //设置为同时接收
        characteristics.setSequential(false);
        userTask.setAssignee(assignee);
        userTask.setLoopCharacteristics(characteristics);
        userTask.setCandidateUsers(userIds);
        return userTask;
    }

    @Override
    public UserTask createCountersignCandidateGroupsTask(String id, String name,
                                                         String assigneeList, String assigneeName,
                                                         String completionCondition, String assignee,
                                                         List<String> roleIds) {



        UserTask userTask = new UserTask();
        userTask.setId(id);
        userTask.setName(name);

        MultiInstanceLoopCharacteristics characteristics = new MultiInstanceLoopCharacteristics();
        // 审批人集合参数
        characteristics.setInputDataItem(assigneeList);
        // 迭代集合
        characteristics.setElementVariable(assigneeName);

        // 完成条件
        characteristics.setCompletionCondition(completionCondition);
        //设置为同时接收
        characteristics.setSequential(false);
        userTask.setAssignee(assignee);
        userTask.setLoopCharacteristics(characteristics);
        StringBuilder sb = new StringBuilder();
        roleIds.stream().forEach(str->{
            sb.append(str).append(",");
        });
        sb.deleteCharAt(sb.length()-1);
        //设置会签监听
        userTask.setExecutionListeners(handleListener(sb.toString()));
        return userTask;
    }

    private List<ActivitiListener> handleListener(String roleList) {
        List<ActivitiListener> listeners = new ArrayList<>();
        ActivitiListener activitiListener = new ActivitiListener();
        // 事件类型
        activitiListener.setEvent(ExecutionListener.EVENTNAME_START);
        // 监听器类型 delegateExpression
        activitiListener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION);
        // 设置实现
        activitiListener.setImplementation("${groupCounterSignListener}");
        List<FieldExtension> fieldExtensions = new ArrayList<>();
        FieldExtension roleListField = new FieldExtension();
        roleListField.setFieldName("roleList");
        roleListField.setStringValue(roleList);
        fieldExtensions.add(roleListField);
        activitiListener.setFieldExtensions(fieldExtensions);
        listeners.add(activitiListener);
        return listeners;
    }


    @Override
    public UserTask createCountersignAssigneeTask(String id, String name,
                                                  String assigneeName,
                                                  String completionCondition,
                                                  String assignee) {
        UserTask userTask = new UserTask();
        userTask.setId(id);
        userTask.setName(name);

        MultiInstanceLoopCharacteristics characteristics = new MultiInstanceLoopCharacteristics();

        // 迭代集合
        characteristics.setElementVariable(assigneeName);

        // 完成条件
        characteristics.setCompletionCondition(completionCondition);
        //设置为同时接收
        characteristics.setSequential(false);
        userTask.setAssignee(assignee);
        userTask.setLoopCharacteristics(characteristics);

        characteristics.setInputDataItem(assignee);
        return userTask;
    }

    @Override
    public ServiceTask createServiceTask(String id, String name, List<CustomProperty> properties) {
        ServiceTask serviceTask = new ServiceTask();
        serviceTask.setId(id);
        serviceTask.setName(name);
        serviceTask.setCustomProperties(properties);
        return serviceTask;
    }

    @Override
    public SequenceFlow createSequenceFlow(String sourceRef, String targetRef) {
        SequenceFlow sequenceFlow = new SequenceFlow();
        sequenceFlow.setSourceRef(sourceRef);
        sequenceFlow.setTargetRef(targetRef);
        return sequenceFlow;
    }

    @Override
    public SequenceFlow createSequenceFlow(String sourceRef, String targetRef, String name, String expression) {
        SequenceFlow sequenceFlow = new SequenceFlow();
        sequenceFlow.setSourceRef(sourceRef);
        sequenceFlow.setTargetRef(targetRef);
        sequenceFlow.setName(name);
        if (StrUtil.isNotEmpty(expression)) {
            sequenceFlow.setConditionExpression(expression);
        }
        return sequenceFlow;
    }

    @Override
    public ExclusiveGateway createExclusiveGateway(String id, String name) {
        ExclusiveGateway exclusiveGateway = new ExclusiveGateway();
        exclusiveGateway.setId(id);
        exclusiveGateway.setName(name);
        return exclusiveGateway;
    }

    @Override
    public ParallelGateway createParallelGateway(String id, String name) {
        ParallelGateway parallelGateway = new ParallelGateway();
        parallelGateway.setId(id);
        parallelGateway.setName(name);
        return parallelGateway;
    }

    @Override
    public EndEvent createEndEvent() {
        EndEvent endEvent = new EndEvent();
        endEvent.setId(BpmnDesignerConstants.END_EVENT);
        return endEvent;
    }
}
